import sys
import os
from functools import partial
import logging 
import gc

from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

from network.network import ClientSocket
from network.package import *

from book import Book

from widgets.toolbars import BookToolBar, LibraryToolBar
from widgets.tab import Tab
from utils.epub import readBook
from library import *

logger = logging.getLogger(__name__)

jsonPack = JsonPackage()
bytePack = BytePackage()

class QImageFactory:
    def __init__(self, parent):
        self.parent = parent

    def getImage(self, image_name):
        icon_path = f'images/{image_name}.svg'

        this_qicon = QIcon(icon_path)
        return this_qicon

class View(QMainWindow):

    def __init__(self, client):
        super(View, self).__init__()

        # TODO to be merged
        self.client = client
        self.imageFactory = QImageFactory(self)
        self.initTabbarAndToolBar()
        self.opened = {}

# TabBar
    def initTabbarAndToolBar(self):

        centralWidget = QWidget()
        self.layout = QVBoxLayout(centralWidget)
        self.tempDir = QTemporaryDir("./temp/").path()
        logger.debug("Temporary Path: " + self.tempDir)
        os.mkdir(self.tempDir)

        # 添加 TabBar
        self.tabWidget = QTabWidget()
        self.layout.addWidget(self.tabWidget)
        self.library = Library()
        # 添加 Tab
        self.tabWidget.addTab(self.library, '书库')

        self.initToolBar()

        self.setCentralWidget(centralWidget)
        self.changeTab(0)

        self.createLibrary()

    def initToolBar(self):

        upload = QAction(self.imageFactory.getImage('add'), "上传", self)
        upload.triggered.connect(self.uploadBooks)

        reload = QAction(self.imageFactory.getImage('refresh'), "刷新", self)
        reload.triggered.connect(self.createLibrary)

        self.libraryToolBar = LibraryToolBar(self)
        self.libraryToolBar.addAction(upload)
        self.libraryToolBar.addAction(reload)
        self.addToolBar(self.libraryToolBar)


        # self.lastChapter = lastChapter
        # self.download = download
        # self.nextChapter = nextChapter

        self.bookToolBar = BookToolBar(self)

        self.bookToolBar.download.triggered.connect(self.downloadBook)

        self.bookToolBar.lastChapter.triggered.connect(self.toLast)
        self.bookToolBar.nextChapter.triggered.connect(self.toNext)
        self.bookToolBar.tocBox.currentIndexChanged.connect(self.setTocPosition)
        self.addToolBar(self.bookToolBar)

        # 设置 TabBar 属性
        self.tabWidget.setTabsClosable(True)
        self.tabWidget.tabBar().setTabButton(0, QTabBar.RightSide, None)
        self.tabWidget.tabCloseRequested.connect(self.closeTab)
        self.tabWidget.currentChanged.connect(self.changeTab)
        self.tabWidget.tabBarClicked.connect(self.tabDisallowLibraryMovement)

    def closeTab(self, idx: int):
        # self.tab.removeTab(idx)

        del(self.opened[self.tabWidget.widget(idx).id])
        self.tabWidget.widget(idx).deleteLater()
        self.tabWidget.widget(idx).setParent(None)
        gc.collect()

    def changeTab(self, idx):
        if 0 == idx:
            self.libraryToolBar.show()
            self.bookToolBar.hide()
        else:
            self.bookToolBar.show()
            self.libraryToolBar.hide()

            curTab = self.tabWidget.currentWidget()
            self.bookToolBar.tocBox.setModel(curTab.tocModel)
            self.bookToolBar.tocTreeView.expandAll()

    def tabDisallowLibraryMovement(self, idx):
        if idx == 0:
            self.tabWidget.setMovable(False)
        else:
            self.tabWidget.setMovable(True)

    def setTocPosition(self, event=None):
        currentIndex = self.bookToolBar.tocTreeView.currentIndex()
        if not currentIndex.data(Qt.UserRole):
            return  # Initial startup might return a None

        # The set_content method is universal
        # It's going to do position tracking
        current_tab = self.tabWidget.currentWidget()
        current_tab.current = currentIndex.data(Qt.UserRole) - 1
        current_tab.setContent()

    def createLibrary(self):

        requestDict = {
            "type": "booklist"
            }
        jsonPack.setData(requestDict)
        recvPack = self.client.send(jsonPack)
        self.books = recvPack.data
        self.library.showBooks(recvPack.data)
        self.library.table.cellDoubleClicked.connect(self.onClickBook)
        self.show()

    def onClickBook(self, row):

        bookInfo = self.library.books[row]
        if bookInfo["id"] in self.opened:
            self.tabWidget.setCurrentWidget(self.opened[bookInfo["id"]])
            return

        requestDict = {
            "type": "bookinfo",
            "id": bookInfo["id"]
            }

        jsonPack.setData(requestDict)
        recvPack = self.client.send(jsonPack)
        Book(recvPack.data, self)

    # def openBook(self, bookName):
    #     contents = readBook(bookName, self.tempDir)

    #     for i in contents:
    #         # 创建新tab
    #         bookData = contents[i]
    #         Tab(bookData, self)
    #         self.opened.append(bookData['path'])
    #     logger.info(
    #         'Successfully opened: ' + ', '.join(self.opened))

    def uploadBooks(self):

        head = {
            "type": "upload",
            }

        filePaths, filter = QFileDialog.getOpenFileNames(self, "上传电子书", "", "Epub Files(*.epub)")

        if not filePaths:
            return
        
        success = False
        for filePath in filePaths:
            filename = os.path.basename(filePath)
            head["filename"] = filename
            f = open(filePath, 'rb')
            bytePack.setData(head, f.read())
            recvPack = self.client.send(bytePack)
            logger.debug(recvPack.data["status"])
            if not recvPack.data["status"]:
                QMessageBox.warning(self, "", recvPack.data["msg"], QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
            else:
                success = True
            f.close()

        if success:
            QMessageBox.information(self, "", "上传成功！",QMessageBox.Yes | QMessageBox.No,QMessageBox.Yes)
            self.createLibrary()

    def downloadBook(self):
        currentIndex = self.bookToolBar.tocTreeView.currentIndex()
        current_tab = self.tabWidget.currentWidget()

        requestDict = {
            "type": "download",
            "id": current_tab.id
            }
        jsonPack.setData(requestDict)

        savePath, _ = QFileDialog.getSaveFileName(self, "下载", current_tab.title + ".epub", "epub文件(*.epub)")
        if savePath:
            recvPack = self.client.send(jsonPack)
            try:
                f = open(savePath, mode = "wb")
                f.write(recvPack.data)
                f.close()
            except:
                QMessageBox.critical(self, "警告", "文件下载失败！",QMessageBox.Yes | QMessageBox.No,QMessageBox.Yes)
                return

            QMessageBox.information(self, "提示", "文件下载成功！",QMessageBox.Yes | QMessageBox.No,QMessageBox.Yes)
    
    def toNext(self):
        currentIndex = self.bookToolBar.tocTreeView.currentIndex()
        current_tab = self.tabWidget.currentWidget()
        current_tab.current += 1

        current_tab.setContent()

    def toLast(self):
        currentIndex = self.bookToolBar.tocTreeView.currentIndex()
        current_tab = self.tabWidget.currentWidget()
        current_tab.current -= 1

        current_tab.setContent()
